package com.zmn.oms.business.impl.wechat;

import org.apache.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.oms.business.interfaces.messageV1.app.MessageSendAppService;
import com.zmn.oms.business.interfaces.messageV1.common.MessageGetSendInfoService;
import com.zmn.oms.business.interfaces.warranty.OrderWarrantyBService;
import com.zmn.oms.business.interfaces.wechat.WechatQrScanBService;
import com.zmn.oms.business.interfaces.work.OrderWorkListBService;
import com.zmn.oms.business.interfaces.work.masterwork.MasterWorkBService;
import com.zmn.oms.common.constant.MessageRuleIdConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.model.dto.work.masterwork.MasterVisitQrDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkQuery;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.oms.services.interfaces.changerecord.OrderChangeRecordService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.base.plat.engine.common.constant.DubboConsts;
import com.zmn.saas.common.enums.wechat.WechatTemplatSkipTypeEnum;
import com.zmn.saas.dubbo.dto.wechat.WechatCustomMessageDIO;
import com.zmn.saas.dubbo.interfaces.wechat.WechatTemplateMessageModifyRemoteService;
import com.zmn.uuc.common.dio.user.UserBindMobileNoCaptchaByUserIdDIO;
import com.zmn.uuc.common.dro.user.UserDetailDRO;
import com.zmn.uuc.dubbo.interfaces.user.UserBindRemoteService;
import com.zmn.uuc.dubbo.interfaces.user.UserListRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 微信扫码业务相关
 * @author: LuJia
 * @version: v1.0
 * @since: 2019/11/24 16:34
 **/
@Service
@Slf4j
public class WechatQrScanBServiceImpl implements WechatQrScanBService {

    @Autowired
    OrderWorkService orderWorkService;
    @Autowired
    OrderDetailService orderDetailService;
    @Autowired
    OrderExtendService orderExtendService;
    @Autowired
    OrderWorkListBService orderWorkListBService;
    @Autowired
    OrderWarrantyService orderWarrantyService;
    @Autowired
    OrderWarrantyBService orderWarrantyBService;
    @Autowired
    MasterWorkBService masterWorkBService;
    @Autowired
    MessageSendAppService messageSendAppService;
    @Autowired
    OrderChangeRecordService orderChangeRecordService;
    @Autowired
    MessageGetSendInfoService messageGetSendInfoService;
    @Value("${spring.profiles.active}")
    String active;
    @Value("${spring.mq.topic.ums:''}")
    String umsTopic;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private WechatTemplateMessageModifyRemoteService wechatTemplateMessageModifyRemoteService;
    @Reference(version = com.zmn.uuc.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private UserBindRemoteService userBindRemoteService;
    @Reference(version = com.zmn.uuc.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private UserListRemoteService userListRemoteService;
    @Autowired
    private ZmnMQSender zmnMQSender;


    @Override
    public void processMasterVisit(Long orderId, Integer shopId, Long userId, String openId, String nickname, String appName, String unionId) {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

        if (Objects.isNull(orderWork)) {
            log.error("#oms#processMasterAmountPay#{} 订单不存在", orderId);
            return;
        }

        // 大于已上门状态
        boolean disableStatus = orderWork.getStatus() > OrderStatusConsts.WORK_STATUS_VISIT;
        if (disableStatus) {
            log.error("#oms#processMasterVisit 当前订单状态不可应用");
            return;
        }

        // 订单是否进行中
        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            log.error("#oms#processMasterVisit 订单已完结");
            return;
        }

        // 是否下单用户扫码
        boolean isInputUserQr = Objects.equals(orderWork.getUserId(), userId);

        if (!isInputUserQr) {
            OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
            // uuc 查询个人用户信息
            ResponseDTO<UserDetailDRO> userResponseDTO = userListRemoteService.getUserDetailById(userId, false);
            if(userResponseDTO.isSuccess() && userResponseDTO.getData() != null){
                UserDetailDRO userDetailDRO = userResponseDTO.getData();
                // 若扫码用户电话与下单用户电话一致，则将临时用户转为正式用户
                if (Objects.equals(userDetailDRO.getMobile(), orderDetail.getTelephone())) {
                    // 调用绑定接口将临时用户转为正式用户
                    UserBindMobileNoCaptchaByUserIdDIO userBindMobileNoCaptchaByUserIdDIO = new UserBindMobileNoCaptchaByUserIdDIO();
                    userBindMobileNoCaptchaByUserIdDIO.setMobile(userDetailDRO.getMobile());
                    userBindMobileNoCaptchaByUserIdDIO.setUserId(orderWork.getUserId());
                    ResponseDTO<Boolean> responseDTO = userBindRemoteService.bindMobileNoCaptchaByUserId(userBindMobileNoCaptchaByUserIdDIO);
                    log.info("调用绑定接口将临时用户转为正式用户： userId {},ResponseDTO [{}]",userId ,responseDTO.getData());
                }
            }
            // 一个扫码用户最多只能绑定除开自己外的10个下单用户的订单，自己下的订单再扫码关联无限制。
            // 如一个扫码用户超过限制后，则在APP和微信公众号都提示：该扫码用户关联订单已达上限
            OrderWorkQuery countQuery = new OrderWorkQuery();
            countQuery.setVisitUserId(userId);
            countQuery.setNotUserId(Lists.newArrayList(userId));
            countQuery.setIncludes(Lists.newArrayList("userId"));
            countQuery.setPageSize(1000);
            List<EsOrderWork> orderWorkList = orderWorkListBService.listPageOrderWorkByQuery(countQuery);
            orderWorkList = Optional.ofNullable(orderWorkList).orElse(Lists.newArrayList());
            Set<Long> userIdSet = orderWorkList.stream().map(EsOrderWork::getUserId).collect(Collectors.toSet());
            log.info("#oms#processMasterVisit#user orderId:{}, orderUserId:{}, openUserId:{}, userIdSet:{} ", orderId, orderWork.getUserId(), userId, JSON.toJSONString(userIdSet));
            int count = 1000;
            if (Objects.equals(active, "prod")) { // 生产环境
                count = 10;
            }
            // 线上演示，冯玉强 工程师ID 22523， 肖琳琳 工程师ID 142930、143775 限制扫码1000次数
            if (Objects.equals(orderWork.getMasterId(), 22523) || Objects.equals(orderWork.getMasterId(),142930) || Objects.equals(orderWork.getMasterId(),143775)) {
                count = 1000;
            }
            if (userIdSet.size() >= count && !userIdSet.contains(orderWork.getUserId())) {
              //  ResultDTO resultDTO = ClientPushUtil.sendInfo(String.valueOf(orderWork.getMasterId()),"该扫码用户关联订单已达上限", "上门扫码", String.valueOf(orderWork.getWorkId()), String.valueOf(GlobalConsts.NONE), String.valueOf(orderWork.getPlatWork()));
                log.info("#ums#processMasterVisit 该扫码用户关联订单已达上限 app push result : {}", openId);
                sendCustomerMessage(orderWork.getPlatWork(), openId, "该扫码用户关联订单已达上限", orderWork);
                return;
            }
        }

        // 绑定上门用户
        orderWork.setVisitUserId(userId);
        orderWorkService.updateVisitUserId(orderWork);

        log.info("#ums#processMasterVisit 上门扫码记录日志开始");
        // 记录日志
        MasterVisitQrDTO qrDTO = new MasterVisitQrDTO();
        qrDTO.setOperator("微信用户");
        qrDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_USER);
        qrDTO.setOperatorId(userId);
        qrDTO.setOperatorPlat(orderWork.getPlatWork());
        qrDTO.setOpenId(openId);
        qrDTO.setOrderId(orderWork.getOrderId());
        qrDTO.setWorkId(orderWork.getWorkId());
        qrDTO.setDbOrderWork(orderWork);
        qrDTO.setNickname(nickname);
        qrDTO.setAppName(appName);
        qrDTO.setUnionId(unionId);
        masterWorkBService.visitUserQrCode(qrDTO);
        log.info("#ums#processMasterVisit 上门扫码记录日志结束");

        // 上门扫码push推送
        Map<String, Object> params = Maps.newHashMap();
        params.put("order_id", String.valueOf(orderWork.getOrderId()));
        params.put("work_id", String.valueOf(orderWork.getWorkId()));
        messageSendAppService.pushAppMessageInfo(MessageRuleIdConsts.PUSH_MSG_RULEID_VISIT_QR_CODE, JSON.toJSONString(params),orderWork);

        // 扫码发送给ums mq 通知该用户
        if (NumberUtil.isNotNullOrZero(orderWork.getVisitUserId())) {
            String key = "send_ums_visit_user_id_" + orderWork.getVisitUserId();
            zmnMQSender.send(umsTopic, OmsMqTagConsts.ZMN_TOPIC_UMS_VISIT_SCAN_QR, key, String.valueOf(orderWork.getVisitUserId()));
        }
//        sendCustomerMessage(orderWork.getPlatWork(), openId, "绑定成功");
        // 更新工单扫码操作状态
        OrderExtend orderExtend = new OrderExtend();
        orderExtend.setExtId(orderWork.getOrderId());
        orderExtend.setOperateVisitScan(GlobalConsts.YES);
        orderExtendService.updateOrderExtend(orderExtend);
    }

    @Override
    public void processUserAttention(Long orderId, Integer shopId, Long userId, String openId, String nickname, String appName, String unionId) {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

        if (Objects.isNull(orderWork)) {
            log.error("#oms#processMasterAmountPay#{} 订单不存在", orderId);
            return;
        }

        // 大于已上门状态
        boolean disableStatus = orderWork.getStatus() > OrderStatusConsts.WORK_STATUS_VISIT;
        if (disableStatus) {
            log.error("#oms#processMasterVisit 当前订单状态不可应用");
            return;
        }

        // 订单是否进行中
        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            log.error("#oms#processMasterVisit 订单已完结");
            return;
        }

        // 是否下单用户扫码
        boolean isInputUserQr = Objects.equals(orderWork.getUserId(), userId);

        if (!isInputUserQr) {
            OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
            // uuc 查询个人用户信息
            ResponseDTO<UserDetailDRO> userResponseDTO = userListRemoteService.getUserDetailById(userId, false);
            if(userResponseDTO.isSuccess() && userResponseDTO.getData() != null){
                UserDetailDRO userDetailDRO = userResponseDTO.getData();
                // 若扫码用户电话与下单用户电话一致，则将临时用户转为正式用户
                if (Objects.equals(userDetailDRO.getMobile(), orderDetail.getTelephone())) {
                    // 调用绑定接口将临时用户转为正式用户
                    UserBindMobileNoCaptchaByUserIdDIO userBindMobileNoCaptchaByUserIdDIO = new UserBindMobileNoCaptchaByUserIdDIO();
                    userBindMobileNoCaptchaByUserIdDIO.setMobile(userDetailDRO.getMobile());
                    userBindMobileNoCaptchaByUserIdDIO.setUserId(orderWork.getUserId());
                    ResponseDTO<Boolean> responseDTO = userBindRemoteService.bindMobileNoCaptchaByUserId(userBindMobileNoCaptchaByUserIdDIO);
                    log.info("调用绑定接口将临时用户转为正式用户： userId {},ResponseDTO [{}]",userId ,responseDTO.getData());
                }
            }
            // 一个扫码用户最多只能绑定除开自己外的10个下单用户的订单，自己下的订单再扫码关联无限制。
            // 如一个扫码用户超过限制后，则在APP和微信公众号都提示：该扫码用户关联订单已达上限
            OrderWorkQuery countQuery = new OrderWorkQuery();
            countQuery.setWeChatScanUserId(userId);
            countQuery.setNotUserId(Lists.newArrayList(userId));
            countQuery.setIncludes(Lists.newArrayList("userId"));
            countQuery.setPageSize(1000);
            List<EsOrderWork> orderWorkList = orderWorkListBService.listPageOrderWorkByQuery(countQuery);
            orderWorkList = Optional.ofNullable(orderWorkList).orElse(Lists.newArrayList());
            Set<Long> userIdSet = orderWorkList.stream().map(EsOrderWork::getUserId).collect(Collectors.toSet());
            log.info("#oms#processMasterVisit#user orderId:{}, orderUserId:{}, openUserId:{}, userIdSet:{} ", orderId, orderWork.getUserId(), userId, JSON.toJSONString(userIdSet));
            int count = 100;
            if (Objects.equals(active, "prod")) { // 生产环境
                count = 10;
            }
            // 线上演示，冯玉强 工程师ID 22523，限制扫码1000次数
            if (Objects.equals(orderWork.getMasterId(), 22523)) {
                count = 1000;
            }
            if (userIdSet.size() >= count && !userIdSet.contains(orderWork.getUserId())) {
                //  ResultDTO resultDTO = ClientPushUtil.sendInfo(String.valueOf(orderWork.getMasterId()),"该扫码用户关联订单已达上限", "上门扫码", String.valueOf(orderWork.getWorkId()), String.valueOf(GlobalConsts.NONE), String.valueOf(orderWork.getPlatWork()));
                log.info("#ums#processMasterVisit 该扫码用户关联订单已达上限 app push result : {}", openId);
                sendCustomerMessage(orderWork.getPlatWork(), openId, "该扫码用户关联订单已达上限", orderWork);
                return;
            }
        }

        // 更新工单扫码用户
        OrderExtend orderExtend = new OrderExtend();
        orderExtend.setExtId(orderWork.getOrderId());
        orderExtend.setWeChatScanUserId(userId);
        orderExtendService.updateOrderExtend(orderExtend);

        // 记录日志
        MasterVisitQrDTO qrDTO = new MasterVisitQrDTO();
        qrDTO.setOperator("微信用户");
        qrDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_USER);
        qrDTO.setOperatorId(userId);
        qrDTO.setOperatorPlat(orderWork.getPlatWork());
        qrDTO.setOpenId(openId);
        qrDTO.setOrderId(orderWork.getOrderId());
        qrDTO.setWorkId(orderWork.getWorkId());
        qrDTO.setDbOrderWork(orderWork);
        qrDTO.setNickname(nickname);
        qrDTO.setAppName(appName);
        qrDTO.setUnionId(unionId);
        masterWorkBService.userAttentionQrCode(qrDTO);

        // 扫码发送给ums mq 通知该用户
        if (NumberUtil.isNotNullOrZero(userId)) {
            String key = "send_ums_visit_user_id_" + userId;
            zmnMQSender.send(umsTopic, OmsMqTagConsts.ZMN_TOPIC_UMS_VISIT_SCAN_QR, key, String.valueOf(userId));
        }
    }

    /**
     * 发送客服消息
     *
     * @param plat
     * @param openId
     * @param content
     */
    private void sendCustomerMessage(Integer plat, String openId, String content, OrderWork orderWork) {

        String thirdAppId =  messageGetSendInfoService.getOrderWeChatThirdAppId(orderWork.getOrderId(), orderWork.getPlatWork());
        WechatCustomMessageDIO dio = WechatCustomMessageDIO.builder()
                .platId(plat)
                .message(content)
                .openId(openId)
                .skipType(WechatTemplatSkipTypeEnum.SKIP_WECHAT_TYPE.getKey())
                .thirdAppId(thirdAppId)
                .build();

        log.debug("#oms#sendCustomerMessage request {}", JSON.toJSONString(dio));
        ResponseDTO responseDTO = wechatTemplateMessageModifyRemoteService.sendWechatCustomMessage(dio);
        log.debug("#oms#sendCustomerMessage response {}", JSON.toJSONString(responseDTO));
    }
}